#include "boot.h"
#include "init.h"
#include "string_utils.h"
#include "nand.h"
#include "uart.h"

static struct tag *params;

void setup_start_tag(void)
{
	params = (struct tag*)0x30000100;

	params->hdr.tag = ATAG_CORE;
	params->hdr.size = tag_size(tag_core);

	params->u.core.flags = 0;
	params->u.core.pagesize = 0;
	params->u.core.rootdev = 0;

	params = tag_next(params);
}

void setup_memory_tags(void)
{
	params->hdr.tag = ATAG_MEM;		//类型
	params->hdr.size = tag_size(tag_mem32);	//这种类型大小

	params->u.mem.start = 0x30000000;
	params->u.mem.size = 64 * 1024 * 1024;

	params = tag_next(params);
}

void setup_commandline_tag(char * cmdline)
{
	int len = strlen(cmdline)+1;
	
	params->hdr.tag = ATAG_CMDLINE;
	//sizeof 中 加3 是为了4字节对齐的操作，可以参考那个公式， 右移2位不懂意思
	params->hdr.size = (sizeof(struct tag_header) + len + 3) >> 2;//tag_size(tag_cmdline);

	strcpy(params->u.cmdline.cmdline, cmdline);

	params = tag_next(params);
}

void setup_end_tag(void)
{
	params->hdr.tag = ATAG_NONE;
	params->hdr.size = 0;
}

void(*myKernel)(int zero, int arch, unsigned int params);

void boot_kernel(void)
{
	volatile unsigned int * p = (volatile unsigned int *)0x30008000;
	char * cmdline = "noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200";
		
	//0、帮内核把串口初始化（进入kernel前如果没初始化就看不了信息）
	uart0_init();

	//1、设置参数
	puts("setup tag or boot params\r\n");
	setup_start_tag();
	setup_memory_tags();
	setup_commandline_tag(cmdline);
	setup_end_tag();

	//2、从nand读取kernel
	puts("copy kernel from nandflash ......\r\n");
	
	//怎么才知道kernel在nand的地址，要分区才知道
	nand_read(0x60000+64, (unsigned char*)0x30008000, 0x20000);
	puts("copy kernel done! \r\n");

	//3、跳转执行----没看懂
	puts("boot kernel ! \r\n");
	myKernel = (void(*)(int, int, unsigned int))0x30008000;	//函数指针指向地址
	myKernel(0, 362, 0x30000100);	//传参并执行函数

	puts("error !!!\r\n");
	return -1;
}

